﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WhittleList.Bll;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace WhittleList.Tests.Mocks
{
    public class FakeUser : Moq.Mock<User>
    {
        public FakeUser(int id, string firstName, string lastName, string emailAddress, string password)
        {
            Setup(x => x.Id).Returns(id);
            SetupProperty(x => x.FirstName, firstName);
            SetupProperty(x => x.LastName, lastName);
            SetupProperty(x => x.EmailAddress, emailAddress);
            Setup(x => x.DisplayName).Returns(GetDisplayName());
            Setup(x => x.AuthenticatePassword(password)).Returns(true);
        }

        public static List<FakeUser> GetList(int number)
        {
            var tmp = new List<FakeUser>();
            while(tmp.Count < number)
            {
                int i = tmp.Count + 1;
                tmp.Add(new FakeUser(i, string.Format("FirstName{0}", i), string.Format("LastName{0}", i), string.Format("email{0}@test.com", i), string.Format("Password{0}", i)));
            }
            return tmp;
        }

        public static List<User> GetObjectList(int number)
        {
            var tmp = GetList(number);
            return tmp.Select(x => x.Object).ToList();
        }

        private string GetDisplayName()
        {
            return string.Concat(this.Object.FirstName, " ", this.Object.LastName);
        }

    }


    /*public static class FakeUserHelpers
    {
        public static IQueryable<User> Convert(this List<FakeUser> items)
        {
            return items.AsQueryable().Convert();
        }

        public static IQueryable<User> Convert(this IQueryable<FakeUser> items)
        {
            return items != null ? items.Select(x => x.Object) : null;
        }
    }*/

    [TestClass]
    public class FakeUserTests
    {
        [TestMethod]
        public void FakeUser_Constructor_Test()
        {
            var tmp = new FakeUser(1, "FirstName", "LastName", "EmailAddress", "Password").Object;
            Assert.AreEqual(1, tmp.Id);
            Assert.AreEqual("FirstName", tmp.FirstName);
            Assert.AreEqual("LastName", tmp.LastName);
            Assert.AreEqual("EmailAddress", tmp.EmailAddress);
            Assert.IsTrue(tmp.AuthenticatePassword("Password"));
        }

        [TestMethod]
        public void FakeUser_FirstNameProperty_Test()
        {
            var tmp = new FakeUser(1, "FirstName", "LastName", "EmailAddress", "Password").Object;
            Assert.AreEqual("FirstName", tmp.FirstName);
            tmp.FirstName = "NewFirstName";
            Assert.AreEqual("NewFirstName", tmp.FirstName);
        }

        [TestMethod]
        public void FakeUser_LastNameProperty_Test()
        {
            var tmp = new FakeUser(1, "FirstName", "LastName", "EmailAddress", "Password").Object;
            Assert.AreEqual("LastName", tmp.LastName);
            tmp.LastName = "NewLastName";
            Assert.AreEqual("NewLastName", tmp.LastName);
        }

        [TestMethod]
        public void FakeUser_EmailProperty_Test()
        {
            var tmp = new FakeUser(1, "FirstName", "LastName", "EmailAddress", "Password").Object;
            Assert.AreEqual("EmailAddress", tmp.EmailAddress);
            tmp.EmailAddress = "NewEmailAddress";
            Assert.AreEqual("NewEmailAddress", tmp.EmailAddress);
        }

        [TestMethod]
        public void GetList_ReturnsList()
        {
            var tmp = FakeUser.GetList(10);
            Assert.AreEqual(10, tmp.Count);
            tmp.ForEach(x => Assert.AreEqual(tmp.IndexOf(x) + 1, x.Object.Id));
        }
    }
}
